from fastapi import APIRouter, Body, Path, Query, Depends
from backend.db.neo4j_driver import neo4j_driver
from backend.utils.logger import logger
from backend.utils.response_filter import filter_sensitive_fields
from backend.schemas.material_transport import MaterialTransportCreate, MaterialTransportUpdate, MaterialTransportDetail
from backend.auth.auth import get_current_user
from datetime import datetime
from typing import Optional
from backend.utils.consts import SERVER_INTERNAL_ERROR_MSG, TRANSPORT_NOT_FOUND_MSG
from backend.cypher_defs.cypher_material_transport import (
    MATCH_TRANSPORT_BY_ID,
    GET_MATERIAL_TRANSPORT_LIST,
    CREATE_MATERIAL_TRANSPORT,
    UPDATE_MATERIAL_TRANSPORT,
    DELETE_MATERIAL_TRANSPORT_REL,
    DELETE_MATERIAL_TRANSPORT,
    CHECK_MATERIAL_TRANSPORT_EXISTS
)
from backend.utils.model_utils import fill_create_update_fields, fill_update_fields

router = APIRouter(prefix="/api/material-transports", tags=["material-transport"])

@router.get(
    "/",
    response_model=dict,
    summary="获取传送方式列表",
    description="支持按传送方式名称或ID模糊查询，返回所有传送方式信息。"
)
async def get_material_transport_list(keyword: Optional[str] = Query(None, description="传送方式名称或ID")):
    try:
        cypher = GET_MATERIAL_TRANSPORT_LIST.format(where=f"WHERE m.materialTransportName CONTAINS $keyword OR m.materialTransportId CONTAINS $keyword" if keyword else "")
        params = {"keyword": keyword}
        result = neo4j_driver.query(cypher, params)
        data = [r["m"] for r in result]
        data = filter_sensitive_fields(data)
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in get_material_transport_list: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.post(
    "/",
    response_model=dict,
    summary="创建传送方式",
    description="创建新的传送方式节点，ID不可重复。"
)
async def create_material_transport(
    body: MaterialTransportCreate,
    current_user: str = Depends(get_current_user)
):
    try:
        cypher = CHECK_MATERIAL_TRANSPORT_EXISTS
        if neo4j_driver.query(cypher, {"materialTransportId": body.materialTransportId}):
            return {"code": 1011, "msg": "传送方式ID已存在", "data": None}
        params = body.dict()
        params = fill_create_update_fields(params, current_user)
        cypher = CREATE_MATERIAL_TRANSPORT
        result = neo4j_driver.query(cypher, params)
        material_transport = result[0]["m"] if result else None
        return {"code": 0, "msg": "success", "data": material_transport}
    except Exception as e:
        logger.error(f"Error in create_material_transport: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.put(
    "/{materialTransportId}",
    response_model=dict,
    summary="更新传送方式信息",
    description="根据ID更新传送方式基本信息。"
)
async def update_material_transport(
    materialTransportId: str = Path(...),
    body: MaterialTransportUpdate = Body(...),
    current_user: str = Depends(get_current_user)
):
    try:
        cypher = MATCH_TRANSPORT_BY_ID
        if not neo4j_driver.query(cypher, {"materialTransportId": materialTransportId}):
            return {"code": 1013, "msg": TRANSPORT_NOT_FOUND_MSG, "data": None}
        set_clauses = []
        params = {"materialTransportId": materialTransportId}
        for k, v in body.dict(exclude_unset=True).items():
            set_clauses.append(f"m.{k} = ${k}")
            params[k] = v
        now_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        set_clauses.append("m.updatedBy = $updatedBy")
        set_clauses.append("m.updatedAt = $updatedAt")
        params["updatedBy"] = current_user
        params["updatedAt"] = now_str
        if set_clauses:
            cypher = UPDATE_MATERIAL_TRANSPORT.replace('{set_clauses}', ', '.join(set_clauses))
            result = neo4j_driver.query(cypher, params)
            material_transport = result[0]["m"] if result else None
        else:
            material_transport = None
        return {"code": 0, "msg": "success", "data": material_transport}
    except Exception as e:
        logger.error(f"Error in update_material_transport: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.delete(
    "/{materialTransportId}",
    response_model=dict,
    summary="删除传送方式",
    description="根据ID删除传送方式节点及其所有关联关系。"
)
async def delete_material_transport(materialTransportId: str = Path(...)):
    try:
        cypher = MATCH_TRANSPORT_BY_ID
        if not neo4j_driver.query(cypher, {"materialTransportId": materialTransportId}):
            return {"code": 1013, "msg": TRANSPORT_NOT_FOUND_MSG, "data": None}
        # 先删除与工台的关系
        cypher = DELETE_MATERIAL_TRANSPORT_REL
        neo4j_driver.query(cypher, {"materialTransportId": materialTransportId})
        # 再删除节点
        cypher = DELETE_MATERIAL_TRANSPORT
        neo4j_driver.query(cypher, {"materialTransportId": materialTransportId})
        return {"code": 0, "msg": "success", "data": None}
    except Exception as e:
        logger.error(f"Error in delete_material_transport: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.get(
    "/{materialTransportId}",
    response_model=dict,
    summary="获取传送方式详情",
    description="根据ID获取传送方式的详细信息。"
)
async def get_material_transport_detail(materialTransportId: str = Path(...)):
    try:
        cypher = MATCH_TRANSPORT_BY_ID
        result = neo4j_driver.query(cypher, {"materialTransportId": materialTransportId})
        data = result[0]["m"] if result else None
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in get_material_transport_detail: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None} 